home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / Draw / Sources / GroupShp.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  24.9 KB  |  834 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                GroupShp.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Author:                Mary Boetcher
  7. //
  8. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #include "ODFDraw.hpp"
  13.  
  14. #ifndef GROUPSHP_H
  15. #include "GroupShp.h"
  16. #endif
  17.  
  18. #ifndef DRAWPART_H
  19. #include "DrawPart.h"
  20. #endif
  21.  
  22. #ifndef DRAWCLIP_H
  23. #include "DrawClip.h"
  24. #endif
  25.  
  26. #ifndef UTILS_H
  27. #include "Utils.h"
  28. #endif
  29.  
  30. #ifndef CONTENT_H
  31. #include "Content.h"
  32. #endif
  33.  
  34. // ----- Part Layer -----
  35.  
  36. #ifndef FWUTIL_H
  37. #include "FWUtil.h"
  38. #endif
  39.  
  40. // ----- OS Layer -----
  41.  
  42. #ifndef FWODGEOM_H
  43. #include "FWODGeom.h"
  44. #endif
  45.  
  46. #ifndef FWGRUTIL_H
  47. #include "FWGrUtil.h"
  48. #endif
  49.  
  50. #ifndef FWACQUIR_H
  51. #include "FWAcquir.h"
  52. #endif
  53.  
  54. #ifndef FWRECSHP_H
  55. #include "FWRecShp.h"
  56. #endif
  57.  
  58. // ----- OpenDoc Includes -----
  59.  
  60. #ifndef SOM_ODTransform_xh
  61. #include <Trnsform.xh>
  62. #endif
  63.  
  64. //========================================================================================
  65. // Runtime Information
  66. //========================================================================================
  67.  
  68. #ifdef FW_BUILD_MAC
  69. #pragma segment odfdrawshapes
  70. #endif
  71.  
  72. //========================================================================================
  73. // class CGroupShape
  74. //========================================================================================
  75.  
  76. FW_DEFINE_CLASS_M1(CGroupShape, CBaseShape)
  77. FW_DEFINE_AUTO(CGroupShape)
  78.  
  79. const FW_ClassTypeConstant LGroupShape = FW_TYPE_CONSTANT('s','h','g','p');
  80. FW_REGISTER_ARCHIVABLE_CLASS(LGroupShape, CGroupShape, CGroupShape::Read, 0, 0, CBaseShape::Write)
  81.  
  82. //----------------------------------------------------------------------------------------
  83. // CGroupShape::CGroupShape
  84. //----------------------------------------------------------------------------------------
  85.  
  86. CGroupShape::CGroupShape(CDrawPart* drawPart) :
  87.     CBaseShape(drawPart, 4, kGroupShape, kFrameOnly),
  88.     fShapeList(NULL)
  89. {
  90.     fShapeList = FW_NEW(CShapeCollection, ());
  91.     FW_END_CONSTRUCTOR
  92. }
  93.  
  94. //----------------------------------------------------------------------------------------
  95. // CGroupShape::CGroupShape
  96. //----------------------------------------------------------------------------------------
  97.  
  98. CGroupShape::CGroupShape(CDrawPart* drawPart, CShapeCollection* shapeList) :
  99.     CBaseShape(drawPart, 4, kGroupShape, kFrameOnly)
  100. {
  101.     fShapeList = FW_NEW(CShapeCollection, ());
  102.     CShapeCollectionIterator it(shapeList);
  103.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  104.     {
  105.         fShapeList->AddLast(shape);
  106.     }
  107.     FW_END_CONSTRUCTOR
  108. }
  109.  
  110. //----------------------------------------------------------------------------------------
  111. // CGroupShape::CGroupShape
  112. //----------------------------------------------------------------------------------------
  113.  
  114. CGroupShape::CGroupShape(CDrawPart* drawPart, FW_CReadableStream& archive) :
  115.     CBaseShape(drawPart, archive)
  116. {
  117.     fShapeList = FW_NEW(CShapeCollection, ());
  118.     FW_END_CONSTRUCTOR
  119. }
  120.  
  121. //----------------------------------------------------------------------------------------
  122. // CGroupShape destructor
  123. //----------------------------------------------------------------------------------------
  124.  
  125. CGroupShape::~CGroupShape()
  126. {
  127.     FW_START_DESTRUCTOR
  128.  
  129.     this->EmptyShapes(true);    // delete shapes
  130.     delete fShapeList;
  131. }
  132.  
  133. //----------------------------------------------------------------------------------------
  134. // CGroupShape::EmptyShapes
  135. //----------------------------------------------------------------------------------------
  136.  
  137. void CGroupShape::EmptyShapes(FW_Boolean deleteShapes)
  138. {
  139.     if (fShapeList)
  140.     {
  141.         CBaseShape* shape;
  142.         while ((shape = fShapeList->First()) != NULL)
  143.         {
  144.             fShapeList->Remove(shape);
  145.             if (deleteShapes)
  146.             {
  147.                 FW_SOMEnvironment ev;
  148.                 shape->Deleted(ev);
  149.                 delete shape;
  150.             }
  151.         }
  152.     }
  153. }
  154.  
  155. //----------------------------------------------------------------------------------------
  156. // CGroupShape::Read
  157. //----------------------------------------------------------------------------------------
  158.  
  159. void* CGroupShape::Read(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  160. {
  161. FW_UNUSED(type);
  162.     // [HLX] This is a hack until I can register object with the archiver
  163.     CDrawReadableStream *drawArchive = (CDrawReadableStream*)&stream;
  164.     CGroupShape* groupShape = FW_NEW(CGroupShape, (drawArchive->GetDrawPart(), stream));
  165.  
  166.     // Read shapes from the stream and add them to the group
  167.     unsigned long count;
  168.     stream >> count;
  169.     for (short i = 0; i<count; i++)
  170.     {
  171.         CBaseShape* theShape = NULL;
  172.         FW_READ_DYNAMIC_OBJECT(stream, &theShape, CBaseShape);
  173.         FW_ASSERT(theShape);
  174.         
  175.         // ----- Add the shape to the group -----
  176.         groupShape->AddShape(theShape);
  177.     }
  178.  
  179.     return groupShape;
  180. }
  181.  
  182. //----------------------------------------------------------------------------------------
  183. // CGroupShape::Flatten
  184. //----------------------------------------------------------------------------------------
  185.  
  186. void CGroupShape::Flatten(FW_CWritableStream& archive)
  187. {    
  188.     CBaseShape::Flatten(archive);
  189.  
  190.     unsigned long count = fShapeList->Count();
  191.     archive << count;
  192.  
  193.     // Write group shapes to the archive
  194.     CShapeCollectionIterator it(fShapeList);
  195.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  196.     {
  197.         FW_WRITE_DYNAMIC_OBJECT(archive, shape, CBaseShape);
  198.     }    
  199. }
  200.  
  201. //----------------------------------------------------------------------------------------
  202. // CGroupShape::CreateShapeOutline
  203. //----------------------------------------------------------------------------------------
  204.  
  205. ODShape* CGroupShape::CreateShapeOutline(Environment* ev)
  206. {
  207.     FW_CRect bounds = GetRectGeometry();
  208.  
  209.         // We don't acquire it because we return it
  210.     ODShape* outline = ::FW_NewODShape(ev, bounds);
  211.  
  212.     ::FW_OutlineODShape(ev, outline, GetPenSize());
  213.  
  214.     return outline;
  215. }
  216.  
  217. //----------------------------------------------------------------------------------------
  218. // CGroupShape::CalcClipShape
  219. //----------------------------------------------------------------------------------------
  220.  
  221. ODShape* CGroupShape::CalcClipShape(Environment* ev)
  222. {
  223.     FW_CAcquiredODShape clipShape = ::FW_NewODShape(ev);
  224.  
  225.     CShapeCollectionIterator it(fShapeList);
  226.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  227.     {
  228.         FW_CAcquiredODShape tempShape = shape->AcquireClipShape(ev);
  229.         clipShape->Union(ev, tempShape);                            
  230.     }
  231.     
  232.     return clipShape.Orphan();
  233. }
  234.  
  235. //----------------------------------------------------------------------------------------
  236. // CGroupShape::GetHandleCenter
  237. //----------------------------------------------------------------------------------------
  238.  
  239. void CGroupShape::GetHandleCenter(short whichHandle, FW_CPoint& center) const
  240. {    
  241.     FW_CRect bounds = GetRectGeometry();
  242.  
  243.     switch (whichHandle)
  244.     {
  245.         case kInTopLeftCorner:
  246.             center.x = bounds.left;
  247.             center.y = bounds.top;
  248.             break;
  249.         case kInTopRightCorner:
  250.             center.x = bounds.right;
  251.             center.y = bounds.top;
  252.             break;
  253.         case kInBottomLeftCorner:
  254.             center.x = bounds.left;
  255.             center.y = bounds.bottom;
  256.             break;
  257.         case kInBottomRightCorner:
  258.             center.x = bounds.right;
  259.             center.y = bounds.bottom;
  260.             break;
  261.     }
  262. }
  263.  
  264. //----------------------------------------------------------------------------------------
  265. // CGroupShape::GetMapRects
  266. //----------------------------------------------------------------------------------------
  267.  
  268. void CGroupShape::GetMapRects(short whichHandle, const FW_CPoint& mouseLoc,
  269.                               FW_CRect& srcRect, FW_CRect& dstRect)
  270. {
  271.     srcRect = GetRectGeometry();
  272.     dstRect = srcRect;
  273.     
  274.     switch (whichHandle)
  275.     {
  276.         case kInTopLeftCorner:
  277.             dstRect.left = mouseLoc.x;
  278.             dstRect.top = mouseLoc.y;
  279.             break;
  280.         case kInTopRightCorner:
  281.             dstRect.right = mouseLoc.x;
  282.             dstRect.top = mouseLoc.y;
  283.             break;
  284.         case kInBottomLeftCorner:
  285.             dstRect.left = mouseLoc.x;
  286.             dstRect.bottom = mouseLoc.y;
  287.             break;
  288.         case kInBottomRightCorner:
  289.             dstRect.right = mouseLoc.x;
  290.             dstRect.bottom = mouseLoc.y;
  291.             break;
  292.     }
  293. }
  294.  
  295. //----------------------------------------------------------------------------------------
  296. // CGroupShape::GetRectGeometry
  297. //----------------------------------------------------------------------------------------
  298. // [HLX] should be cached
  299.  
  300. FW_CRect CGroupShape::GetRectGeometry() const
  301. {
  302.     // Calculate the boundary rectangle for our shapes
  303.     FW_CRect rect = FW_kZeroRect;
  304.     if (fShapeList->Count() != 0)
  305.     {
  306.         FW_Boolean first = true;
  307.         FW_CRect tempRect;
  308.     
  309.         CShapeCollectionIterator it(fShapeList);
  310.         for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  311.         {
  312.             shape->GetDragRect(tempRect);
  313.             if (first)
  314.                 rect = tempRect;
  315.             else
  316.                 rect |= tempRect;
  317.             first = false;
  318.         }
  319.     }
  320.     return rect;
  321. }
  322.  
  323. //----------------------------------------------------------------------------------------
  324. // CGroupShape::HitTest
  325. //----------------------------------------------------------------------------------------
  326.  
  327. FW_Boolean CGroupShape::HitTest(Environment* ev, FW_CGraphicContext& gc, const FW_CMouseEvent& theMouseEvent) const
  328. {
  329.     // Perform HitTest on each shape in this group
  330.     CShapeCollectionIterator it(fShapeList);
  331.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  332.     {
  333.         if (shape->HitTest(ev, gc, theMouseEvent))
  334.             return true;
  335.     }
  336.  
  337.     return false;    
  338. }
  339.  
  340. //----------------------------------------------------------------------------------------
  341. // CGroupShape::MapShape
  342. //----------------------------------------------------------------------------------------
  343.  
  344. void CGroupShape::MapShape(Environment* ev, const FW_CRect& srcRect, const FW_CRect& dstRect)
  345. {
  346. #if 1
  347.     FW_CRect beforeRect = GetRectGeometry();
  348.     FW_CRect afterRect = beforeRect;
  349.     afterRect.Map(srcRect, dstRect);
  350.  
  351.     // Map each shape in this group
  352.     CShapeCollectionIterator it(fShapeList);
  353.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  354.     {
  355.         shape->MapShape(ev, beforeRect, afterRect);
  356.     }
  357. #else
  358.     // Map each shape in this group
  359.     CShapeCollectionIterator it(fShapeList);
  360.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  361.     {
  362.         shape->MapShape(ev, srcRect, dstRect);
  363.     }
  364. #endif
  365. }
  366.  
  367. //----------------------------------------------------------------------------------------
  368. // CGroupShape::OffsetShape
  369. //----------------------------------------------------------------------------------------
  370.  
  371. void CGroupShape::OffsetShape(Environment* ev, FW_Fixed xDelta, FW_Fixed yDelta)
  372. {
  373. //    CheckPromise(ev); [HLX] Do not call CheckPromise from OffsetShape or end up in a infinity loop
  374. //                        because externalize of a pict calls OffsetShape
  375.     ClearCache(ev);
  376.  
  377.     // Offset each shape in this group
  378.     CShapeCollectionIterator it(fShapeList);
  379.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  380.     {
  381.         shape->OffsetShape(ev, xDelta, yDelta);
  382.     }
  383. }
  384.  
  385. //----------------------------------------------------------------------------------------
  386. // CGroupShape::RenderShape
  387. //----------------------------------------------------------------------------------------
  388.  
  389. void CGroupShape::RenderShape(Environment* ev, ODFacet* facet, FW_CGraphicContext& gc)
  390. {    
  391.     // Render each shape in this group
  392.     CShapeCollectionIterator it(fShapeList);
  393.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  394.     {
  395.         if (facet != NULL || shape->GetShapeType() != kProxyShape)
  396.             shape->RenderShape(ev, facet, gc);
  397.     }
  398. }
  399.  
  400. //----------------------------------------------------------------------------------------
  401. // CGroupShape::ResizeFeedback
  402. //----------------------------------------------------------------------------------------
  403.  
  404. void CGroupShape::ResizeFeedback(FW_CGraphicContext& gc, const FW_CInk& ink, const FW_CStyle& style, 
  405.                                  short whichHandle, const FW_CPoint& mouseLoc)
  406. {
  407.     FW_CRect srcRect, dstRect;
  408.     GetMapRects(whichHandle, mouseLoc, srcRect, dstRect);
  409.     dstRect.Sort();
  410.     OutlineShape(gc, ink, style, dstRect);
  411. }
  412.  
  413. //----------------------------------------------------------------------------------------
  414. // CGroupShape::SetShapeGeometry
  415. //----------------------------------------------------------------------------------------
  416.  
  417. void CGroupShape::SetShapeGeometry(const FW_CPoint& anchorPoint, const FW_CPoint& currentPoint)
  418. {
  419.     FW_CRect rect = GetRectGeometry();
  420.  
  421.     if (anchorPoint.x < currentPoint.x)
  422.     {
  423.         rect.left = anchorPoint.x;
  424.         rect.right = currentPoint.x;
  425.     }
  426.     else
  427.     {
  428.         rect.left = currentPoint.x;
  429.         rect.right = anchorPoint.x;
  430.     }
  431.     
  432.     if (anchorPoint.y < currentPoint.y)
  433.     {
  434.         rect.top = anchorPoint.y;
  435.         rect.bottom = currentPoint.y;
  436.     }
  437.     else
  438.     {
  439.         rect.top = currentPoint.y;
  440.         rect.bottom = anchorPoint.y;
  441.     }
  442.  
  443.     /* How to change group shape's geometry? */
  444. }
  445.  
  446. //----------------------------------------------------------------------------------------
  447. // CGroupShape::OutlineShape
  448. //----------------------------------------------------------------------------------------
  449.  
  450. void CGroupShape::OutlineShape(FW_CGraphicContext& gc, const FW_CInk& ink, const FW_CStyle& style, const FW_CRect& rect)
  451. {
  452.     FW_CRect bounds(rect);
  453.     AdjustRectForPenSize(bounds, style.GetPenSize());
  454.     FW_CRectShape::RenderRect(gc,
  455.                               bounds,
  456.                               FW_kFrame,
  457.                               ink, style);
  458. }
  459.  
  460. //------------------------------------------------------------------------------
  461. //    CGroupShape::RestoreShape
  462. //------------------------------------------------------------------------------
  463.  
  464. void CGroupShape::RestoreShape(Environment* ev)
  465. {
  466.     CBaseShape::RestoreShape(ev);
  467.     
  468.     // Call RestoreShape on each shape in this group
  469.     CShapeCollectionIterator it(fShapeList);
  470.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  471.     {
  472.         shape->RestoreShape(ev);
  473.     }
  474. }
  475.  
  476. //----------------------------------------------------------------------------------------
  477. // CGroupShape::Removed
  478. //----------------------------------------------------------------------------------------
  479.  
  480. void CGroupShape::Removed(Environment* ev)
  481. {
  482.     CBaseShape::Removed(ev);
  483.     
  484.     // Call Removed on each shape in this group
  485.     CShapeCollectionIterator it(fShapeList);
  486.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  487.     {
  488.         shape->Removed(ev);
  489.     }
  490. }
  491.  
  492. //------------------------------------------------------------------------------
  493. //    CGroupShape::Deleted - the shape is going to be deleted
  494. //------------------------------------------------------------------------------
  495.  
  496. void CGroupShape::Deleted(Environment* ev)
  497. {
  498.     CBaseShape::Deleted(ev);
  499.     
  500.     // Call Deleted on each shape in this group
  501.     CShapeCollectionIterator it(fShapeList);
  502.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  503.     {
  504.         shape->Deleted(ev);
  505.     }
  506. }
  507.  
  508. //----------------------------------------------------------------------------------------
  509. // CGroupShape::SelectShape
  510. //----------------------------------------------------------------------------------------
  511.  
  512. void CGroupShape::SelectShape(Environment* ev, FW_Boolean state)
  513. {
  514.     CBaseShape::SelectShape(ev, state);
  515.     
  516.     // ----- Select all the shapes in this group ----
  517.     CShapeCollectionIterator it(fShapeList);
  518.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  519.     {
  520.         shape->SelectShape(ev, state);
  521.     }
  522. }
  523.  
  524. //----------------------------------------------------------------------------------------
  525. // CGroupShape::SubtractToWorkingClip
  526. //----------------------------------------------------------------------------------------
  527.  
  528. void CGroupShape::SubtractToWorkingClip(Environment* ev, 
  529.                                         CDrawFacetClipper* facetClipper, 
  530.                                         ODFacet* containingFacet, 
  531.                                         ODShape* workingClip,
  532.                                         ODShape* tempShape,
  533.                                         ODShape* limitShape)
  534. {
  535.     /* [MEB] kludge - prevent crash on copy/paste a group shape containing proxies */
  536.     if (CountProxyShapes(ev) != 0)
  537.     {
  538.         CBaseShape::SubtractToWorkingClip(ev, facetClipper, containingFacet, workingClip, tempShape, limitShape);
  539.         return;
  540.     }
  541.  
  542.     // Call SubtractToWorkingClip on each shape in this group
  543.     CShapeCollectionIterator it(fShapeList);
  544.     for (CBaseShape* shape = it.Last(); it.IsNotComplete(); shape = it.Previous())
  545.     {
  546.         shape->SubtractToWorkingClip(ev, facetClipper, containingFacet, workingClip, tempShape, limitShape);
  547.     }
  548. }
  549.  
  550. //----------------------------------------------------------------------------------------
  551. // CGroupShape::AddShape
  552. //----------------------------------------------------------------------------------------
  553.  
  554. void CGroupShape::AddShape(CBaseShape* shape)
  555. {
  556.     fShapeList->AddLast(shape);
  557. }
  558.  
  559. //----------------------------------------------------------------------------------------
  560. // CGroupShape::CountShapes
  561. //----------------------------------------------------------------------------------------
  562.  
  563. unsigned long CGroupShape::CountShapes() const
  564. {
  565.     return fShapeList->Count();
  566. }
  567.  
  568. //------------------------------------------------------------------------------
  569. //    CGroupShape::CountProxyShapes
  570. //------------------------------------------------------------------------------
  571.  
  572. unsigned long CGroupShape::CountProxyShapes(Environment* ev) const
  573. {
  574.     unsigned long count = 0;
  575.     
  576.     CShapeCollectionIterator it(fShapeList);
  577.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  578.     {
  579.         if (shape->GetShapeType() == kProxyShape)
  580.             count++;
  581.         else if (shape->GetShapeType() == kGroupShape)
  582.             count += ((CGroupShape*) shape)->CountProxyShapes(ev);    // recursive call
  583.     }
  584.     
  585.     return count;
  586. }
  587.  
  588. //----------------------------------------------------------------------------------------
  589. // CGroupShape::GetFirstShape
  590. //----------------------------------------------------------------------------------------
  591.  
  592. CBaseShape* CGroupShape::GetFirstShape() const
  593. {
  594.     return fShapeList->First();
  595. }
  596.  
  597. //----------------------------------------------------------------------------------------
  598. // CGroupShape::RemoveShapes
  599. //----------------------------------------------------------------------------------------
  600.  
  601. void CGroupShape::RemoveShapes()
  602. {
  603.     this->EmptyShapes(false);
  604. }
  605.  
  606. //----------------------------------------------------------------------------------------
  607. // CGroupShape::Remove1Shape
  608. //----------------------------------------------------------------------------------------
  609.  
  610. void CGroupShape::Remove1Shape(CBaseShape* shape)
  611. {
  612.     fShapeList->Remove(shape);
  613. }
  614.  
  615. //----------------------------------------------------------------------------------------
  616. // CGroupShape::ChangeFillColor
  617. //----------------------------------------------------------------------------------------
  618.  
  619. void CGroupShape::ChangeFillColor(Environment* ev, const FW_CColor& color)
  620. {
  621.     CBaseShape::ChangeFillColor(ev, color);
  622.  
  623.     CShapeCollectionIterator it(fShapeList);
  624.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  625.     {
  626.         shape->ChangeFillColor(ev, color);
  627.     }
  628. }
  629.  
  630. //----------------------------------------------------------------------------------------
  631. // CGroupShape::ChangeFrameColor
  632. //----------------------------------------------------------------------------------------
  633.  
  634. void CGroupShape::ChangeFrameColor(Environment* ev, const FW_CColor& color)
  635. {
  636.     CBaseShape::ChangeFrameColor(ev, color);
  637.  
  638.     CShapeCollectionIterator it(fShapeList);
  639.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  640.     {
  641.         shape->ChangeFrameColor(ev, color);
  642.     }
  643. }
  644.  
  645. //----------------------------------------------------------------------------------------
  646. // CGroupShape::ChangeFillPattern
  647. //----------------------------------------------------------------------------------------
  648.  
  649. void CGroupShape::ChangeFillPattern(Environment* ev, const FW_CPattern& pattern)
  650. {
  651.     CBaseShape::ChangeFillPattern(ev, pattern);
  652.  
  653.     CShapeCollectionIterator it(fShapeList);
  654.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  655.     {
  656.         shape->ChangeFillPattern(ev, pattern);
  657.     }
  658. }
  659.  
  660. //----------------------------------------------------------------------------------------
  661. // CGroupShape::ChangeFramePattern
  662. //----------------------------------------------------------------------------------------
  663.  
  664. void CGroupShape::ChangeFramePattern(Environment* ev, const FW_CPattern& pattern)
  665. {
  666.     CBaseShape::ChangeFramePattern(ev, pattern);
  667.  
  668.     CShapeCollectionIterator it(fShapeList);
  669.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  670.     {
  671.         shape->ChangeFramePattern(ev, pattern);
  672.     }
  673. }
  674.  
  675. //----------------------------------------------------------------------------------------
  676. // CGroupShape::ChangePenSize
  677. //----------------------------------------------------------------------------------------
  678.  
  679. void CGroupShape::ChangePenSize(Environment* ev, FW_Fixed newPenSize)
  680. {
  681.     CBaseShape::ChangePenSize(ev, newPenSize);
  682.  
  683.     CShapeCollectionIterator it(fShapeList);
  684.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  685.     {
  686.         shape->ChangePenSize(ev, newPenSize);
  687.     }
  688. }
  689.  
  690. //----------------------------------------------------------------------------------------
  691. // CGroupShape::ChangeRenderVerb
  692. //----------------------------------------------------------------------------------------
  693.  
  694. void CGroupShape::ChangeRenderVerb(Environment* ev, unsigned short renderVerb)
  695. {
  696.     CBaseShape::ChangeRenderVerb(ev, renderVerb);
  697.  
  698.     CShapeCollectionIterator it(fShapeList);
  699.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  700.     {
  701.         shape->ChangeRenderVerb(ev, renderVerb);
  702.     }
  703. }
  704.  
  705. //----------------------------------------------------------------------------------------
  706. // CGroupShape::SetSubscribeLink
  707. //----------------------------------------------------------------------------------------
  708.  
  709. void CGroupShape::SetSubscribeLink(Environment* ev, CDrawSubscribeLink* subscribeLink)
  710. {
  711.     CBaseShape::SetSubscribeLink(ev, subscribeLink);
  712.  
  713.     CShapeCollectionIterator it(fShapeList);
  714.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  715.     {
  716.         shape->SetSubscribeLink(ev, subscribeLink);
  717.     }
  718. }
  719.  
  720. //========================================================================================
  721. //    class CAllShapeIterator
  722. //========================================================================================
  723.  
  724. FW_DEFINE_AUTO(CAllShapeIterator)
  725.  
  726. //----------------------------------------------------------------------------------------
  727. //    CAllShapeIterator::CAllShapeIterator
  728. //----------------------------------------------------------------------------------------
  729.  
  730. CAllShapeIterator::CAllShapeIterator(CShapeCollection* shapeList) :
  731.     fIter(NULL),
  732.     fTempList(NULL)
  733. {
  734.     fTempList = FW_NEW(CShapeCollection, ());
  735.     PrivFlattenList(shapeList);
  736.     fIter = FW_NEW(CShapeCollectionIterator, (fTempList));
  737.     FW_END_CONSTRUCTOR    
  738. }
  739.  
  740. //----------------------------------------------------------------------------------------
  741. //    CAllShapeIterator::CAllShapeIterator
  742. //----------------------------------------------------------------------------------------
  743.  
  744. CAllShapeIterator::CAllShapeIterator(CDrawContent* content) :
  745.     fIter(NULL),
  746.     fTempList(NULL)
  747. {
  748.     fTempList = FW_NEW(CShapeCollection, ());
  749.     PrivFlattenList(content->fShapeList);
  750.     fIter = FW_NEW(CShapeCollectionIterator, (fTempList));
  751.     FW_END_CONSTRUCTOR    
  752. }
  753.  
  754. //----------------------------------------------------------------------------------------
  755. //    CAllShapeIterator::CAllShapeIterator
  756. //----------------------------------------------------------------------------------------
  757.  
  758. CAllShapeIterator::~CAllShapeIterator()
  759. {
  760.     FW_START_DESTRUCTOR
  761.     delete fTempList;
  762.     delete fIter;
  763. }
  764.  
  765. //----------------------------------------------------------------------------------------
  766. //    CAllShapeIterator::First
  767. //----------------------------------------------------------------------------------------
  768.  
  769. CBaseShape* CAllShapeIterator::First()
  770. {
  771.     return fIter->First();
  772. }
  773.  
  774. //----------------------------------------------------------------------------------------
  775. //    CAllShapeIterator::Next
  776. //----------------------------------------------------------------------------------------
  777.  
  778. CBaseShape*    CAllShapeIterator::Next()
  779. {
  780.     return fIter->Next();
  781. }
  782.  
  783. //----------------------------------------------------------------------------------------
  784. //    CAllShapeIterator::IsNotComplete
  785. //----------------------------------------------------------------------------------------
  786.  
  787. FW_Boolean CAllShapeIterator::IsNotComplete()
  788. {
  789.     return fIter->IsNotComplete();
  790. }
  791.  
  792. //----------------------------------------------------------------------------------------
  793. //    CAllShapeIterator::Last
  794. //----------------------------------------------------------------------------------------
  795.  
  796. CBaseShape* CAllShapeIterator::Last()
  797. {
  798.     return fIter->Last();
  799. }
  800.  
  801. //----------------------------------------------------------------------------------------
  802. //    CAllShapeIterator::Previous
  803. //----------------------------------------------------------------------------------------
  804.  
  805. CBaseShape*    CAllShapeIterator::Previous()
  806. {
  807.     return fIter->Previous();
  808. }
  809.  
  810. //----------------------------------------------------------------------------------------
  811. //    CAllShapeIterator::PrivFlattenList
  812. //----------------------------------------------------------------------------------------
  813.  
  814. void CAllShapeIterator::PrivFlattenList(CShapeCollection* shapeList)
  815. {
  816.     CShapeCollectionIterator it(shapeList);
  817.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  818.     {
  819.         if (shape->GetShapeType() == kGroupShape)
  820.             PrivFlattenList(((CGroupShape*)shape)->GetShapeList());
  821.         else
  822.             fTempList->AddLast(shape);
  823.     }
  824. }
  825.  
  826. //----------------------------------------------------------------------------------------
  827. //    CAllShapeIterator::CountShapes
  828. //----------------------------------------------------------------------------------------
  829.  
  830. unsigned long CAllShapeIterator::CountShapes()
  831. {
  832.     return fTempList->Count();
  833. }
  834.